﻿
namespace Patterns4Net.ArchitectureExplorer.Diagram.Services.AbstractionLevels
{
    using System.Collections.Generic;
    using System.ComponentModel.Composition;
    using System.IO;
    using System.Linq;
    using Patterns4Net.ArchitectureExplorer.Diagram.Services;
    using Patterns4Net.Attributes;
    using Patterns4Net.Core.AbstractionLevel;

    [DiagramUpdaterExport(Order = 200)]
    public class PatternsAbstractionLevelProvider : DiagramVisitor, IDiagramUpdater
    {
        private readonly IEnumerable<IPatternLevelProvider> providers;

        [ImportingConstructor]
        public PatternsAbstractionLevelProvider([ImportMany]IEnumerable<IPatternLevelProvider> providers)
        {
            this.providers = providers;
        }

        public void UpdateDiagram(Diagram diagram, TextWriter output)
        {
            diagram.Accept(this);
        }

        public override void Visit(TypeInfo typeInfo)
        {
            var levels = new List<AbstractionLevel>();
            foreach (var pattern in typeInfo.Patterns)
            {
                foreach (var provider in this.providers)
                {
                    var level = provider.GetLevel(pattern.Pattern);
                    if (level.HasValue)
                    {
                        levels.Add(level.Value);
                    }
                }
            }

            if (levels.Any())
            {
                typeInfo.AbstractionLevel = levels.GetHigherLevel();
            }
        }
    }
}
